package com.anxuan.agent.agent;

import cn.hutool.core.util.StrUtil;
import com.anxuan.agent.agent.model.AgentState;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 抽象基础代理类，用于管理代理状态和执行流程
 *
 * 提供状态转换，内存管理和基于步骤的执行循环的基础功能
 */
@Slf4j
@Data
public abstract class BaseAgent {

    String name;

    String systemPrompt;

    private String nextStepPrompt;

    private AgentState state = AgentState.IDLE;

    //执行步骤控制
    private int currentStep = 0;
    private int maxSteps = 10;


    private ChatClient chatClient;


    // Memory 记忆(需要自主维护绘画上下文)
    private  List<Message> messageList = new ArrayList<>();


    public String run(String userPrompt){

        //基础校验
        if(this.state != AgentState.IDLE){
            throw new RuntimeException("Cannet run agent from state : " + this.state);

        }

        if(StrUtil.isBlank(userPrompt)){
            throw new RuntimeException("userPrompt is empty");
        }

        //执行，更行状态
        this.state = AgentState.IDLE;

        //记录消息上下文
        messageList.add(new UserMessage(userPrompt));

        //保存结果列表
        ArrayList<String> results = new ArrayList<>();
        try {
//执行循环
            for (int i = 0; i < maxSteps && state != AgentState.FINISHED; i++) {
                int stepNumber = i + 1;

                currentStep = stepNumber;

                log.info("Executing step {}/{}", stepNumber, maxSteps);

                //单步执行
                String stepResult = step();
                String result = "Step " + stepNumber + ": " + stepResult;

                results.add(result);

            }

            //检查是否超出步骤限制
            if(currentStep >= maxSteps){
                state = AgentState.FINISHED;
                results.add("Terminated: Reached max steps (" + maxSteps + ")");
            }
        }catch (Exception e){

            state = AgentState.ERROR;
            log.error("error executing agent", e);
            return "执行错误" + e.getMessage();
        }finally {
            this.cleanup();
        }



        return String.join("\n", results);



    }

    public SseEmitter runSteam(String userPrompt){

        //创建一个超时时间较长的SseEmitter
        SseEmitter sseEmitter = new SseEmitter(180000L);

        CompletableFuture.runAsync(
                () -> {
                    try {
                        //基础校验
                        if(this.state != AgentState.IDLE){
                            sseEmitter.send("错误，无法从状态运行代理: " + this.state);
                            sseEmitter.complete();
                            return;

                        }

                        if(StrUtil.isBlank(userPrompt)){
                            sseEmitter.send("错误，不能用空提示词运行代理: " + this.state);
                            sseEmitter.complete();
                            throw new RuntimeException("userPrompt is empty");
                        }
                    }catch (Exception e){
                        sseEmitter.completeWithError(e);
                    }


                    //执行，更行状态
                    this.state = AgentState.IDLE;

                    //记录消息上下文
                    messageList.add(new UserMessage(userPrompt));

                    //保存结果列表
                    ArrayList<String> results = new ArrayList<>();
                    try {
                    //执行循环
                        for (int i = 0; i < maxSteps && state != AgentState.FINISHED; i++) {
                            int stepNumber = i + 1;

                            currentStep = stepNumber;

                            log.info("Executing step {}/{}", stepNumber, maxSteps);

                            //单步执行
                            String stepResult = step();
                            String result = "Step " + stepNumber + ": " + stepResult;

                            results.add(result);

                            //输出当前每一步到SSE
                            sseEmitter.send(result);

                        }

                        //检查是否超出步骤限制
                        if(currentStep >= maxSteps){
                            state = AgentState.FINISHED;
                            results.add("Terminated: Reached max steps (" + maxSteps + ")");
                            sseEmitter.send("执行结束，达到最大步骤(" + maxSteps + ")");
                        }
                        sseEmitter.complete();
                    }catch (Exception e){
                        state = AgentState.ERROR;
                        log.error("error executing agent", e);
                        try {
                            sseEmitter.send("执行错误: " + e.getMessage());
                            sseEmitter.complete();
                        } catch (IOException ex) {
                            sseEmitter.completeWithError(ex);
                        }
                    }finally {
                        this.cleanup();
                    }
                }
        );


        sseEmitter.onTimeout(() -> {
            this.state = AgentState.ERROR;
            this.cleanup();
            log.warn("SSE connection timeout");
        });

        sseEmitter.onCompletion(() -> {
            if(this.state == AgentState.RUNNING){
                this.state = AgentState.FINISHED;
            }
            this.cleanup();
            log.info("SSE connection completed");
        });
        return sseEmitter;






    }
    public abstract String step();


    protected void cleanup(){

    }


}
